package com.ecoolex.ying.space.admin.graphql;

import java.time.Instant;
import java.util.Date;

import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;

import com.google.common.collect.Lists;
import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.pojo.Sorting;
import com.ecoolex.framework.common.util.Assert;
import com.ecoolex.framework.common.util.BeanUtil;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.modularize.api.auth.admin.AdminMemberAuthority;
import com.ecoolex.framework.modularize.api.auth.annotation.AdminAuthoritativeRegister;
import com.ecoolex.framework.modularize.api.auth.user.ConsumerMember;
import com.ecoolex.framework.modularize.api.auth.user.ConsumerMemberManager;
import com.ecoolex.framework.modularize.api.service.storage.FileSize;
import com.ecoolex.framework.modularize.api.service.storage.MimeType;
import com.ecoolex.framework.modularize.api.service.storage.StorageInfo;
import com.ecoolex.framework.modularize.api.service.storage.StorageService;
import com.ecoolex.framework.modularize.api.service.storage.Upload;
import com.ecoolex.framework.modularize.api.service.storage.UploadLimit;
import com.ecoolex.framework.modularize.api.service.storage.UploadSource;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module;
import com.ecoolex.framework.web.api.graphql2.annotation.QueryField;
import com.ecoolex.framework.web.api.graphql2.annotation.Source;
import com.ecoolex.framework.web.api.graphql2.annotation.TypeField;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module.Type;
import com.ecoolex.framework.web.api.graphql2.annotation.MutationField;
import com.ecoolex.ying.space.admin.core.AdminConstant;
import com.ecoolex.ying.space.entity.PushMessage;
import com.ecoolex.ying.space.entity.UserIdentityAuthentication;
import com.ecoolex.ying.space.entity.PushMessage.Column;
import com.ecoolex.ying.space.pojo.AddPushMessageDTO;
import com.ecoolex.ying.space.pojo.EditPushMessageDTO;
import com.ecoolex.ying.space.ws.PushMessageService;
import com.ecoolex.ying.space.ws.UserIdentityAuthenticationService;

@GraphQL2Module(type = Type.Admin, description = "推送管理")
@AdminAuthoritativeRegister(parentKey = AdminConstant.AUTH_MODULE_KEY, key = PushMessageGraphql.AUTH, name = "推送管理")
public class PushMessageGraphql {

	public static final String AUTH = AdminConstant.AUTH_MODULE_KEY + "-PUSHMESSAGE";
	
	@Reference
	private PushMessageService pushMessageService;
	
	@Autowired
	private StorageService storageService;
	
	@Autowired
	private ConsumerMemberManager consumerMemberManager;
	
	@Reference
	private UserIdentityAuthenticationService userIdentityAuthenticationService;
	
	@TypeField(type = PushMessage.class,field = "releaseUser",description = "发布者用户信息")
	public ConsumerMember getCommentUser(@Source PushMessage source) {
		return consumerMemberManager.getByUserId(source.getReleaseUserId());
	}
	
	@TypeField(type = PushMessage.class,field = "pushStatus",description = "推送状态：1 已推送 ，2 已定时")
	public Integer pushStatus(@Source PushMessage source) {
		return source.getPushTime().after(Date.from(Instant.now())) ? 2 : 1;
	}
	
	@TypeField(type = PushMessage.class,field = "canEdit",description = "能编辑")
	public boolean canEdit(@Source PushMessage source) {
		return source.getPushTime().after(Date.from(Instant.now()));
	}
	
	@TypeField(type = PushMessage.class,field = "coverImage",description = "推送封面图")
	public StorageInfo coverImage(@Source PushMessage source) {
		return storageService.get(source.getCoverImage());
	}
	
	public static final String AUTH_GET = AUTH+"-GET";
	
	@QueryField(field = "pushMessage", description = "推送详情")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_GET, name = "推送详情")
	public PushMessage get(@NonNull Integer id,AdminMemberAuthority user) {
		user.assertAuth(AUTH_GET);
		return pushMessageService.getPushMessageById(id);
	}
	
	private static final String AUTH_QUERY = AUTH + "-QUERY";
	
	@QueryField(field = "pushMessageList", description = "推送列表")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_QUERY, name = "推送列表")
	public Pagination<PushMessage> query(String title,Date startTime,Date endTime,@NonNull Sorting[] sorts,@NonNull Page page,AdminMemberAuthority user){
		user.assertAuth(AUTH_QUERY);
		return pushMessageService.queryPushMessage(title, startTime, endTime, sorts, page);
	}
	
	@MutationField(field = "uploadPushMessageCoverImage", description = { "上传推送封面" })
	public StorageInfo uploadCoverImage(@NonNull Upload request, AdminMemberAuthority user) {
		if (!user.auth(AUTH_ADD) && !user.auth(AUTH_EDIT)) {
			user.notAuthority();
		}
		UploadSource uploadSource = new UploadSource("PushMessage","CoverImage");
        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(2));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());
        
        return storageService.upload(request,uploadSource,uploadLimit);
	}
	
	private static final String AUTH_ADD = AUTH + "-ADD";
	
	@MutationField(field = "addPushMessage", description = "添加推送")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_ADD, name = "添加推送")
	public PushMessage add(@NonNull AddPushMessageDTO record,AdminMemberAuthority user) {
		user.assertAuth(AUTH_ADD);
		//校验传入的userId是否在用户认证表中是否存在
		UserIdentityAuthentication userIdentityAuthentication = userIdentityAuthenticationService.getByUserId(record.getReleaseUserId());
		Assert.isTrue(Check.notNull(userIdentityAuthentication), ResultCode.VERIFY.build(1), "平台官方用户不存在");
		return pushMessageService.addPushMessage(record, user.userName());
	}
	
	private static final String AUTH_EDIT = AUTH + "-EDIT";
	
	@MutationField(field = "editPushMessage", description = "编辑推送")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_EDIT, name = "编辑推送")
	public PushMessage edit(@NonNull EditPushMessageDTO record,AdminMemberAuthority user) {
		user.assertAuth(AUTH_EDIT);
		PushMessage old = pushMessageService.getPushMessageById(record.getId());
		Assert.isTrue(Check.notNull(old), ResultCode.VERIFY.build(1), "推送不存在");
		//校验传入的userId是否在用户认证表中是否存在
		UserIdentityAuthentication userIdentityAuthentication = userIdentityAuthenticationService.getByUserId(record.getReleaseUserId());
		Assert.isTrue(Check.notNull(userIdentityAuthentication), ResultCode.VERIFY.build(1), "平台官方用户不存在");
		BeanUtil.copy(record,
				old,
				Lists.newArrayList(Column.deleted, Column.createUser, Column.createTime).stream().map(
					Column::getJavaProperty).toArray(String[]::new));
		return pushMessageService.editPushMessage(old, user.userName());
	}
	
	private static final String AUTH_DEL = AUTH + "-DEL";
	
	@MutationField(field = "delPushMessage", description = "删除推送")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_DEL, name = "删除推送")
	public boolean delete(@NonNull Integer id,AdminMemberAuthority user) {
		user.assertAuth(AUTH_DEL);
		PushMessage old = pushMessageService.getPushMessageById(id);
		Assert.isTrue(Check.notNull(old), ResultCode.VERIFY.build(1), "推送不存在");
		pushMessageService.deletePushMessage(old, user.userName());
		return true;
	} 
}
